<template>
  <view
    class="cal-box"
    :style="{
      '--color': color,
      '--activeColor': activeColor,
      '--shadow': shadow + '29',
    }"
  >
    <view
      class="cal"
      :style="{
        background: bgColor,
      }"
    >
      <view class="cal-top">
        <view class="prev" @click="changeWeek('prev')" v-if="button">上一周</view>
        <text class="date">
          <div class="before" />
          {{ nowSelectDateString }}
          <div class="after" />
        </text>
        <view class="next" @click="changeWeek('next')" v-if="button">下一周</view>
      </view>

      <view class="cal-content">
        <view class="cal-ul cal-weeks">
          <view class="cal-li" v-for="(item, i) of baseData.weekTitles" :key="i">
            <text>{{ item }}</text>
          </view>
        </view>

        <swiper
          :current="current"
          ref="calSwiper"
          class="cal-swiper"
          :duration="200"
          circular
          @animationfinish="swiperFisnish"
        >
          <swiper-item v-for="(days, i) of weeks" :key="i">
            <view class="cal-ul cal-days">
              <view
                class="cal-li"
                v-for="(item, j) of days"
                :key="j"
                @click="changeSelected(item)"
              >
                <view
                  class="cal-day-li"
                  :class="{
                    'cal-day-li-selected':
                      item.timeSpan == baseData.selectedDate.timeSpan,
                  }"
                >
                  <text>{{ item.d }}</text>
                </view>
                <view class="bage" v-if="item.timeSpan == baseData.selectedDate.timeSpan">
                </view>
              </view>
            </view>
          </swiper-item>
        </swiper>
      </view>
    </view>
    <view class="cal-bottom">
      <slot />
    </view>
    <view class="cal-button" v-if="showBtn" @click="backToday">今</view>
  </view>
</template>

<script setup>
import { ref, onMounted, watch, computed } from "vue";
const props = defineProps({
  // 默认选中日期（支持时间戳、日期字符串）
  defaultDate: {
    type: [String, Number],
    default: 0,
  },
  // 是否显示切换按钮
  button: {
    type: Boolean,
    default: false,
  },
  // 背景颜色
  bgColor: {
    type: String,
    default: "linear-gradient(180deg, #ABD49D 0%, #4EA770 100%)",
  },
  // 字体颜色
  color: {
    type: String,
    default: "#fff",
  },
  // 选中颜色
  activeColor: {
    type: String,
    default: "#4EA770",
  },
  // 阴影颜色
  shadow: {
    type: String,
    default: "#4EA770",
  },
});
const emit = defineEmits(["changeDate"]);

const weeks = ref([]); // 周列表
const propDate = ref(); // 选中日期
const current = ref(0); // 翻页
const baseData = ref({
  weekTitles: ["日", "一", "二", "三", "四", "五", "六"],
  current: 0,
  selectedDate: {
    d: null, // 在当前月份中的天
    ym: "", // 年月拼接
    timeSpan: 0, // 时间戳
  },
});

onMounted(() => {
  propDate.value = props.defaultDate == 0 ? new Date() : new Date(props.defaultDate);
  initData();
});

// 选中日期
const nowSelectDateString = computed(() => {
  let m = baseData.value.selectedDate.m;
  if (m) {
    let month = m.getMonth() + 1 < 10 ? `0${m.getMonth() + 1}` : m.getMonth() + 1;
    let day = m.getDate() < 10 ? `0${m.getDate()}` : m.getDate();
    return `${m.getFullYear()}-${month}-${day}`;
  } else {
    return "";
  }
});

// 显示今日按钮
const showBtn = computed(() => {
  let m = baseData.value.selectedDate.m;
  if (m) {
    if (
      m.getFullYear() == new Date().getFullYear() &&
      m.getMonth() == new Date().getMonth() &&
      m.getDate() == new Date().getDate()
    ) {
      return false;
    } else {
      return true;
    }
  } else {
    return false;
  }
});

watch(
  props,
  (val) => {
    setTimeout(() => {
      propDate.value = val.defaultDate == 0 ? new Date() : new Date(val.defaultDate);
      initData();
    }, 0);
  },
  { deep: true, immediate: true }
);

// 初始化日期
const initData = () => {
  let lastSat = new Date(propDate.value);
  baseData.value.selectedDate = {
    d: lastSat.getDate(),
    ym: `${lastSat.getFullYear()}${lastSat.getMonth() + 1}`,
    timeSpan: +lastSat,
    m: new Date(lastSat),
  };

  current.value = 0;
  // 寻找到距离当前日期最近的周六
  while (lastSat.getDay() != 6) lastSat.setDate(lastSat.getDate() + 1);
  weeks.value[0] = getWeekDaysByLastSat(lastSat);
  weeks.value[1] = getWeekDaysByWeeks(weeks.value[0], true);
  weeks.value[2] = getWeekDaysByWeeks(weeks.value[0], false);
};

// 返回今天
const backToday = () => {
  current.value = 0;
  changeWeeks(true, 0);
  console.log("weeks",weeks.value)
  // let timeSpan = baseData.value.selectedDate.timeSpan;
  // let date = new Date(timeSpan);
  // let year = new Date().getFullYear();
  // let month = new Date().getMonth();
  // let day = new Date().getDate();

  // date.setFullYear(year);
  // date.setMonth(month);
  // date.setDate(day);
  // const obj = {
  //   d: day,
  //   ym: `${year}${month + 1}`,
  //   timeSpan: +date,
  //   m: new Date(date),
  // };
  // changeSelected(obj);
  propDate.value = new Date();
  initData();
};

// 滚动完成
const swiperFisnish = (e) => {
  let current = e.detail.current;
  changeWeeks(current > baseData.value.current, current);
  baseData.value.upCurrIndex = current;
};

// 切换周
const changeWeeks = (direction, current) => {
  let nextIndex = current + 1 > 2 ? 0 : current + 1;
  let prevIndex = current - 1 < 0 ? 2 : current - 1;
  weeks.value[nextIndex] = getWeekDaysByWeeks(weeks.value[current], true);
  weeks.value[prevIndex] = getWeekDaysByWeeks(weeks.value[current], false);
};

// 修改周时间
const changeWeek = (type) => {
  let nextIndex = current.value + 1 > 2 ? 0 : current.value + 1;
  let prevIndex = current.value - 1 < 0 ? 2 : current.value - 1;
  current.value = type == "prev" ? prevIndex : nextIndex;
};

// 通过周六数据获取一周的数据
const getWeekDaysByLastSat = (lastSat) => {
  lastSat = new Date(lastSat);
  let reuslt = [];
  for (var i = 0; i < 7; i++) {
    reuslt.push({
      d: lastSat.getDate(),
      ym: `${lastSat.getFullYear()}${lastSat.getMonth() + 1}`,
      timeSpan: +lastSat,
      m: new Date(lastSat),
    });
    lastSat.setDate(lastSat.getDate() - 1);
  }
  return reuslt.reverse();
};

// 通过一周的数据获取本周的上周或下周
const getWeekDaysByWeeks = (weeks, direction) => {
  // 下周
  if (direction) {
    let nextLastSat = new Date(weeks[weeks.length - 1].timeSpan);
    nextLastSat.setDate(nextLastSat.getDate() + 7);
    return getWeekDaysByLastSat(nextLastSat);
  }
  // 上周
  else {
    let prevLstSat = new Date(weeks[0].timeSpan);
    prevLstSat.setDate(prevLstSat.getDate() - 1);
    return getWeekDaysByLastSat(prevLstSat);
  }
};
// 修改当前选中
const changeSelected = (item) => {
  console.log("item::", item);
  if (baseData.value.selectedDate.timeSpan != item.timeSpan) {
    baseData.value.selectedDate = {
      ...item,
      m: new Date(item.timeSpan),
    };
    emit("changeDate", baseData.value.selectedDate);
  }
};
</script>

<style lang="scss" scoped>
uni-swiper {
  height: 128rpx !important;
}
.cal-box {
  --color: #fff;
  --activeColor: #3ea3ff;
  --shadow: #007aff29;
  margin: 20rpx 40rpx 0;
  .cal {
    width: auto;
    height: 254rpx;
    border-radius: 30rpx;
    overflow: hidden;
    padding-bottom: 40rpx;
    border-radius: 20rpx 20rpx 0 0;
    box-shadow: 0 0 20rpx 2rpx var(--shadow);
    .cal-top {
      display: flex;
      justify-content: space-between;
      width: auto;
      height: 91rpx;
      line-height: 91rpx;
      text-align: center;
      box-sizing: border-box;
      padding: 0 30rpx;
      .prev,
      .next {
        color: var(--color);
        font-size: 26rpx;
        width: 100rpx;
      }
      .date {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 32rpx;
        font-weight: bold;
        color: var(--color);
        pointer-events: none;
        .before {
          width: 6px;
          height: 12px;
          margin-right: 2px;
          display: inline-block;
          background-color: var(--color);
          position: relative;
          border-radius: 8rpx;
          &::before {
            content: "";
            position: absolute;
            left: -10px;
            top: 4px;
            width: 6px;
            height: 8px;
            display: inline-block;
            border-radius: 8rpx;
            background-color: var(--color);
          }
        }
        .after {
          width: 6px;
          height: 12px;
          margin-left: 2px;
          display: inline-block;
          background-color: var(--color);
          position: relative;
          border-radius: 8rpx;
          &::before {
            content: "";
            position: absolute;
            left: 10px;
            top: 4px;
            width: 6px;
            height: 8px;
            display: inline-block;
            border-radius: 8rpx;
            background-color: var(--color);
          }
        }
      }
    }
  }
  .cal-content {
    padding: 15rpx 0 40rpx;
    .cal-ul {
      position: relative;
      display: flex;
      justify-content: space-between;
      .cal-li {
        width: calc(100% / 7);
        text-align: center;
      }
    }
    .cal-swiper {
      margin-top: 20rpx;
    }
    .cal-weeks {
      font-size: 26rpx;
      font-weight: 600;
      color: var(--color);
    }
    .cal-days {
      font-size: 28rpx;
      color: var(--color);
    }
    .cal-day-li {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 63rpx;
      height: 63rpx;
      margin: 0 auto;
    }
    .cal-day-li-selected {
      background-color: var(--color);
      border-radius: 50%;
      color: var(--activeColor) !important;
    }
    .bage {
      background-color: var(--color);
      width: 6px;
      height: 6px;
      border-radius: 50%;
      margin: 10px auto;
    }
  }
  .cal-bottom {
    background-color: #fff;
    border-radius: 0 0 20rpx 20rpx;
    box-shadow: 0 0 20rpx 2rpx var(--shadow);
    box-shadow: 0px 0px 10px 1px rgba(117, 117, 117, 0.16);
    padding: 20rpx;
  }
  .cal-button {
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
    font-size: 28rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    color: var(--color);
    background-color: var(--activeColor);
    position: fixed;
    bottom: 200rpx;
    right: 40rpx;
  }
}
</style>
